package org.jpass.dc.common.dao;

import java.io.Serializable;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.jpass.dc.common.bean.Page;
import org.jpass.dc.common.util.HibernateUtil;

/**
 *.
 * 
 * @author long
 * 
 * @param <T>
 *            Domain type.
 */
public abstract class GenericDao<T> {

	private final Class<T> clazz;

	public GenericDao(Class<T> clazz) {
		this.clazz = clazz;
	}

	/**
	 * Query object by specified id.
	 */
	@SuppressWarnings("unchecked")
	public T queryById(Serializable id) {
		Session session = HibernateUtil.getSession();
		session.beginTransaction(); // 开启事务
		T t = (T) session.get(clazz, id);
		session.close();
		return t;
	}

	/**
	 * Create an domain object.
	 */
	public boolean save(T t) {
		boolean result = false;
		Session session = HibernateUtil.getSession();
		session.beginTransaction(); // 开启事务
		Serializable io = session.save(t); // 保存信息
		if (io != null) {
			result = true;
		}
		session.getTransaction().commit(); // 提交事务
		session.close();

		return result;
	}
	
	public void delete(T t) throws Exception {
		Session session = HibernateUtil.getSession();
		session.beginTransaction();
		session.delete(t);
		session.getTransaction().commit();
		session.close();
	}

	/**
	 * Delete an object.
	 */
	@SuppressWarnings("unchecked")
	public void delete(String hql) {
		Session session = HibernateUtil.getSession();
		session.beginTransaction();
		Query query = session.createQuery(hql);
		List<T> list = query.list();
		Iterator<T> it = list.iterator();
		T t = null;
		while (it.hasNext()) {
			t = (T) it.next();
			session.delete(t);
		}
		session.getTransaction().commit();
		session.close();
	}

	/**
	 * 批量删除记录
	 * 
	 * @param ids
	 */
	public int bulkDelete(String hql, String[] idList) throws Exception {
		Session session = HibernateUtil.getSession();
		session.beginTransaction();
		// 执行删除操作
		Query query = session.createQuery(hql);
		for (int i = 0; i < idList.length; i++) {
			query.setString(i, idList[i]);
		}
		int deletedEntities = query.executeUpdate();
		session.getTransaction().commit();
		session.close();

		return deletedEntities;
	}

	/**
	 * Update an object.
	 */
	public void update(T t) {
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		session.update(t);
		tx.commit();
		session.close();
	}

	@SuppressWarnings("unchecked")
	public T query(String hql) {
		Session session = HibernateUtil.getSession();
		Query query = session.createQuery(hql);
		List<T> list = query.list();
		Iterator<T> it = list.iterator();
		T t = null;
		while (it.hasNext()) {
			t = (T) it.next();
		}
		session.close();
		return t;
	}
	@SuppressWarnings("unchecked")
	public List<T> queryAllUserList(String hql) {
		Session session = HibernateUtil.getSession();
		Query query = session.createQuery(hql);
		List<T> list = query.list();
		return list;
	}
	
	@SuppressWarnings("unchecked")
	public List<T> findObjListByHql(String hql) {
		Session session = HibernateUtil.getSession();
		Query query = session.createQuery(hql);
		List<T> list = query.list();
		return list;
	}

	/**
	 * 查询数据的记录数
	 * 
	 * @param select
	 * @param values
	 * @return
	 */
	protected Object queryForObject(final String select, final Object[] values) {
		Session session = HibernateUtil.getSession();
		
		try {
			Query query = session.createQuery(select);
			if (values != null) {
				for (int i = 0; i < values.length; i++)
					query.setParameter(i, values[i]);
			}
			// session.createCriteria(this.clazz)
			return query.uniqueResult();
		} catch(Exception e) {
			e.printStackTrace();
			return null;
		}
		
	}

	/**
	 * 查询数据表的记录，包括数据表的总记录数
	 * 
	 * @param selectCount
	 *            查询总记录数的sql语句
	 * @param select
	 *            查询记录的sql语句
	 * @param values
	 *            查询条件
	 * @param page
	 * @return
	 */
	@SuppressWarnings("unchecked")
	protected List<T> queryForList(final String selectCount,
			final String select, final Object[] values, final Page page) {
		Long count = (Long) queryForObject(selectCount, values);
		page.setTotalCount(count.intValue());
		if (page.isEmpty())
			return Collections.EMPTY_LIST;
		return queryForList(select, values, page);
	}

	/**
	 * 分页查询数据表的记录
	 * 
	 * @param select
	 *            查询记录的sql语句
	 * @param values
	 *            查询条件
	 * @return
	 */
	@SuppressWarnings("unchecked")
	protected List<T> queryForList(final String select, final Object[] values,
			final Page page) {
		Session session = HibernateUtil.getSession();
		try {
			Query query = session.createQuery(select);
			if (values != null) {
				for (int i = 0, len = values.length; i < len; i++)
					query.setParameter(i, values[i]);
			}
			if (page != null) {
				query.setFirstResult(page.getFirstResult()).setMaxResults(
						page.getPageSize());
			}
			List<T> list = query.list();
			session.close();

			return list;
		} catch(Exception e) {
			e.printStackTrace();
			return null;
		}
		
	}

	/**
	 * 执行更新操作
	 * @param updateHql
	 * @param values
	 * @return
	 */
	protected int executeUpdate(final String updateHql, final Object[] values) {
		Session session = HibernateUtil.getSession();
		Transaction tx = session.beginTransaction();
		int rows = 0;
		try {
			Query query = session.createQuery(updateHql);
			if (values != null) {
				for (int i = 0, len = values.length; i < len; i++)
					query.setParameter(i, values[i]);
			}
			rows = new Integer(query.executeUpdate());
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return rows;
		
	}
}
